package boot.spring.config;

import java.util.LinkedHashMap;
import java.util.Properties;

import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;

import boot.spring.shiro.CustomRealm;

@Configuration
public class shiroConfig {
	//将自己的验证方式(realm)加入容器
    @Bean
    public CustomRealm customRealm() {
        CustomRealm customRealm = new CustomRealm();
        return customRealm;
    }
    
    //权限管理，配置主要是Realm的管理认证
    @Bean
    public SecurityManager securityManager() {
    	//shiro的核心管理器对象
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //注入realm
        securityManager.setRealm(this.customRealm());
        return securityManager;
    }
    /**
	 * 3.shiro过滤器
	 * @return
	 */
	@Bean
	public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {

		System.out.println("22222222是否到了这里-----------------");
		//shiro的过滤器对象，拦截请求进行验证
		ShiroFilterFactoryBean shiroFilterFactoryBean =new ShiroFilterFactoryBean();
		//注入核心管理器
		shiroFilterFactoryBean.setSecurityManager(securityManager);
		//没有登录配置跳转到登录页面（自定义跳转路径）
		shiroFilterFactoryBean.setLoginUrl("http://127.0.0.1:8848/CRM_web/src/login.html");
		//登录后没有权限时设置跳转路劲
		shiroFilterFactoryBean.setUnauthorizedUrl("http://127.0.0.1:8848/CRM_web/src/pages/sysSetup/templateAdmin.html");
		//配置权限访问链，使用linkedHashMap保证有序
		LinkedHashMap<String, String> filterMap=new LinkedHashMap<String, String>();
		/*
		 * 第一个参数：访问路径，第二个：权限
		 * anon：没有限制都可以访问
		 * authc：必须登录后才能访问
		 * user：Remember Me使用
		 * perms：必须有相应的权限才能操作
		 * roles：必须有相应的角色才能操作
		 */
		filterMap.put("/gologin","anon");
		filterMap.put("/RoleController/getRoleByUidCon","anon");
		filterMap.put("/userInfo/login", "anon");
		filterMap.put("/userInfo/register", "anon");
		/*filterMap.put("/user", "roles[user]");
		filterMap.put("/UsersController/UserConAll", "perms");
		filterMap.put("/UsersController/UserConAdd", "perms");*/
		/*filterMap.put("/UsersController/UserConAdd：", "anon");
		filterMap.put("/UsersController/UserConUnlocklock", "anon");
		filterMap.put("/UsersController/UserRoleAdd", "anon");
		filterMap.put("/UsersController/UserRoleRemove", "anon");
		filterMap.put("/UsersController/UserConUnup", "anon");
		filterMap.put("/UsersController/UserConDel", "anon");
		filterMap.put("/UsersController/UserConPwdUp", "anon");*/
		//除了上面配置的特殊请求的权限外其他的所有请求都需要登录权限，这个配置要放在最下面
		//filterMap.put("/**","authc");
		//将权限链设置给过滤器对象user


		shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
		return shiroFilterFactoryBean;
	}
	
	/**
	 * 使用注解设置权限
	 * 解决setUnauthorizedUrl不能跳转的问题
	 */
	@Bean
	public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
	    AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
	    authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
	    return authorizationAttributeSourceAdvisor;
	}


	/**
	 *  开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证
	 * 配置以下两个bean(DefaultAdvisorAutoProxyCreator和AuthorizationAttributeSourceAdvisor)即可实现此功能
	 * @return
	 */
	@Bean
	public static DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {

		DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
		defaultAdvisorAutoProxyCreator.setUsePrefix(true);

		return defaultAdvisorAutoProxyCreator;
	}
	/**
     * 解决： 无权限页面不跳转 shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized") 无效
     * shiro的源代码ShiroFilterFactoryBean.Java定义的filter必须满足filter instanceof AuthorizationFilter，
     * 只有perms，roles，ssl，rest，port才是属于AuthorizationFilter，而anon，authcBasic，auchc，user是AuthenticationFilter，
     * 所以unauthorizedUrl设置后页面不跳转 Shiro注解模式下，登录失败与没有权限都是通过抛出异常。
     * 并且默认并没有去处理或者捕获这些异常。在SpringMVC下需要配置捕获相应异常来通知用户信息
     * @return
     */
    @Bean
    public SimpleMappingExceptionResolver simpleMappingExceptionResolver() {
        SimpleMappingExceptionResolver simpleMappingExceptionResolver=new SimpleMappingExceptionResolver();
        Properties properties=new Properties();
        //setProperty方法的第二个参数必须改为自己定义的无权限页面路径 
        properties.setProperty("org.apache.shiro.authz.UnauthorizedException","/Returns/GetReturns");
        properties.setProperty("org.apache.shiro.authz.UnauthenticatedException","/Returns/GetReturns");
        simpleMappingExceptionResolver.setExceptionMappings(properties);
        return simpleMappingExceptionResolver;
    }
}
